package com.qbw.core.base;

import android.content.Intent;

import androidx.collection.ArrayMap;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.LayoutRes;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import com.lib.util.ResUtil;
import com.qbw.app.utils.LanguageUtils;
import com.lib.util.SPUtils;
import com.qbw.bar.SystemBar;
import com.qbw.core.fragment.LoadingDialogFragment;
import com.qbw.log.XLog;

import java.util.Map;
import java.util.Set;

/**
 * Created by Bond on 2017/01/16 14:13
 * you can contact me at qbaowei@qq.com
 */


public abstract class BaseActivity<B extends ViewDataBinding> extends AppCompatActivity {

    private final String TAG = "[life]";

    private Map<Long, BaseFragment> mFragmentMap;

    protected B mBinding;

    private LoadingDialogFragment mLoadingDialogFragment;

    public B getBinding() {
        return mBinding;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        XLog.v(getLogTag());
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        XLog.v(getLogTag());
    }

    private String getLogTag() {
        return TAG + getClass().getSimpleName();
    }

    protected abstract @LayoutRes
    int getLayoutId();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        onSetStatusBarColor();
        super.onCreate(savedInstanceState);
        XLog.v(getLogTag());
        mBinding = DataBindingUtil.setContentView(this, getLayoutId());
        LanguageUtils.setdefaultLanguage(BaseActivity.this, SPUtils.getInstance().getString("language"));

    }

    public void onSetStatusBarColor() {
        XLog.v(getLogTag());
        SystemBar.setColor(this, true, android.R.color.transparent, false);
    }

    @Override
    public void onActivityReenter(int resultCode, Intent data) {
        super.onActivityReenter(resultCode, data);
        XLog.v(getLogTag());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        XLog.v(getLogTag());
    }

    @Override
    protected void onStart() {
        super.onStart();
        XLog.v(getLogTag());
    }

    @Override
    protected void onResume() {
        super.onResume();
        XLog.v(getLogTag());
        //MobclickAgent.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        XLog.v(getLogTag());
        //MobclickAgent.onPause(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        XLog.v(getLogTag());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        XLog.v(getLogTag());
    }

    @Override
    public void finish() {
        super.finish();
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        XLog.v(getLogTag());
    }

    protected int getContainerViewId() {
        return 0;
    }

    public void switchFragment(long id) {
        if (mFragmentMap == null || mFragmentMap.isEmpty()) {
            return;
        }
        BaseFragment fragment = mFragmentMap.get(id);
        if (null != fragment) {
            hideFragmentExcept(id);
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            if (!fragment.isAdded()) {
                XLog.d("addCommonParams fragment %s", fragment.getClass().getSimpleName());
                transaction.add(getContainerViewId(), fragment);
            }
            XLog.d("show fragment %s", fragment.getClass().getSimpleName());
            transaction.show(fragment);
            transaction.commitAllowingStateLoss();
        } else {
            XLog.e("no fragment for id %d", id);
        }
    }

    public void addFragment(long id, BaseFragment fragment) {
        if (mFragmentMap == null) {
            mFragmentMap = new ArrayMap<>();
        }
        if (mFragmentMap.containsKey(id) && mFragmentMap.get(id) != null) {
            XLog.w("碎片%d已经存在", id);
            return;
        }
        mFragmentMap.put(id, fragment);
    }

    public boolean isFragmentContains(long id) {
        return mFragmentMap != null && !mFragmentMap.isEmpty() && mFragmentMap.containsKey(id);
    }

    private void hideFragmentExcept(long id) {
        if (mFragmentMap == null || mFragmentMap.isEmpty()) {
            return;
        }
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Set<Map.Entry<Long, BaseFragment>> fragments = mFragmentMap.entrySet();
        for (Map.Entry<Long, BaseFragment> fragment : fragments) {
            if (fragment.getKey() != id) {
                BaseFragment baseFragment = fragment.getValue();
                if (baseFragment.isVisible()) {
                    XLog.d("hide fragment %s", baseFragment.getClass().getSimpleName());
                    transaction.hide(baseFragment);
                }
            }
        }
        transaction.commitAllowingStateLoss();
    }

    private void removeAllFragments() {
        if (mFragmentMap == null || mFragmentMap.isEmpty()) {
            return;
        }
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        for (Fragment fragment : mFragmentMap.values()) {
            transaction.remove(fragment);
        }
        transaction.commitAllowingStateLoss();
        mFragmentMap.clear();
        XLog.d("%s:remove all fragments finished.", getLogTag());
    }

    protected void setKeyboardVisibilityListener(final OnKeyboardVisibilityListener onKeyboardVisibilityListener) {
        final View parentView = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
        parentView.getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

                    private boolean alreadyOpen;
                    private final int defaultKeyboardHeightDP = 100;
                    private final int EstimatedKeyboardDP = defaultKeyboardHeightDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
                    private final Rect rect = new Rect();

                    @Override
                    public void onGlobalLayout() {
                        int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                                EstimatedKeyboardDP,
                                parentView.getResources()
                                        .getDisplayMetrics());
                        parentView.getWindowVisibleDisplayFrame(rect);
                        int heightDiff = parentView.getRootView()
                                .getHeight() - (rect.bottom - rect.top);
                        boolean isShown = heightDiff >= estimatedKeyboardHeight;
                        XLog.d("heightDiff[%d], estimatedKeyboardHeight[%d]",
                                heightDiff,
                                estimatedKeyboardHeight);
                        if (isShown == alreadyOpen) {
                            XLog.i("Ignoring global layout change...");
                            return;
                        }
                        alreadyOpen = isShown;
                        onKeyboardVisibilityListener.onVisibilityChanged(isShown);
                    }
                });
    }

    public interface OnKeyboardVisibilityListener {
        void onVisibilityChanged(boolean b);
    }

    public void showLoadingDialog(@StringRes int titleRes) {
        showLoadingDialog(ResUtil.getString(titleRes));
    }

    public void showLoadingDialog(String title) {
        if (this == null ||
                this.isFinishing() ||
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && this.isDestroyed())) {
            return;
        }
        if (mLoadingDialogFragment != null) {
            mLoadingDialogFragment.setTitle(title);
            return;
        }
        mLoadingDialogFragment = LoadingDialogFragment.newInstance(title);
        mLoadingDialogFragment.show(getSupportFragmentManager(), "loading_dialog");
    }

    public void closeLoadingDialog() {
        if (this == null ||
                this.isFinishing() ||
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && this.isDestroyed())) {
            return;
        }
        if (mLoadingDialogFragment != null) {
            mLoadingDialogFragment.dismiss();
            mLoadingDialogFragment = null;
        }
    }

    protected String gs(@StringRes int str) {
        return getResources().getString(str);
    }
}
